{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "376f0d4d-69a9-4846-81c3-c906c800b4c8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "欢迎使用星座运势查询程序！\n",
      "\n",
      "请选择要查询的星座：\n",
      "1. 白羊座\n",
      "2. 金牛座\n",
      "3. 双子座\n",
      "4. 巨蟹座\n",
      "5. 狮子座\n",
      "6. 处女座\n",
      "7. 天秤座\n",
      "8. 天蝎座\n",
      "9. 射手座\n",
      "10. 摩羯座\n",
      "11. 水瓶座\n",
      "12. 双鱼座\n",
      "0. 退出程序\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入选项数字： 1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "API 响应内容：\n",
      "{'date': 20241008, 'name': '白羊座', 'QFriend': '金牛座', 'all': '90', 'color': '青色', 'datetime': '2024年10月08日', 'health': '84', 'love': '100', 'money': '100', 'number': 6, 'summary': '没有外界的干扰，正好可以调整自己的步伐。你可以静下心来，思考自己的目标和计划，制定出更加合理的方案。同时，你也可以利用这个机会，放松自己的身心，让自己更加充满活力。在思考目标和计划时，你可以从多个角度出发，考虑到各种可能的情况，制定出更加全面和详细的方案。在放松身心方面，你可以选择一些适合自己的方式，比如听音乐、阅读、运动等，让自己的心情更加愉悦。此外，你还可以与家人和朋友交流，分享自己的想法和感受，获得他们的支持和鼓励。', 'work': '100', 'resultcode': '200', 'error_code': 0}\n",
      "\n",
      "白羊座的today运势：\n",
      "综合指数：90\n",
      "幸运色：青色\n",
      "幸运数字：6\n",
      "健康指数：84\n",
      "爱情指数：100\n",
      "财运指数：100\n",
      "工作指数：100\n",
      "今日概述：没有外界的干扰，正好可以调整自己的步伐。你可以静下心来，思考自己的目标和计划，制定出更加合理的方案。同时，你也可以利用这个机会，放松自己的身心，让自己更加充满活力。在思考目标和计划时，你可以从多个角度出发，考虑到各种可能的情况，制定出更加全面和详细的方案。在放松身心方面，你可以选择一些适合自己的方式，比如听音乐、阅读、运动等，让自己的心情更加愉悦。此外，你还可以与家人和朋友交流，分享自己的想法和感受，获得他们的支持和鼓励。\n",
      "\n",
      "请选择要查询的星座：\n",
      "1. 白羊座\n",
      "2. 金牛座\n",
      "3. 双子座\n",
      "4. 巨蟹座\n",
      "5. 狮子座\n",
      "6. 处女座\n",
      "7. 天秤座\n",
      "8. 天蝎座\n",
      "9. 射手座\n",
      "10. 摩羯座\n",
      "11. 水瓶座\n",
      "12. 双鱼座\n",
      "0. 退出程序\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "\n",
    "# 基本参数配置\n",
    "apiUrl = 'http://web.juhe.cn/constellation/getAll'\n",
    "apiKey = 'ad173944d1bbe42b742018fe18217278'  # 您提供的API key\n",
    "\n",
    "def get_constellation_fortune(consName, type='today'):\n",
    "    # 接口请求入参配置\n",
    "    requestParams = {\n",
    "        'key': apiKey,\n",
    "        'consName': consName,\n",
    "        'type': type,\n",
    "    }\n",
    "    \n",
    "    try:\n",
    "        # 发起接口网络请求\n",
    "        response = requests.get(apiUrl, params=requestParams)\n",
    "        \n",
    "        # 解析响应结果\n",
    "        if response.status_code == 200:\n",
    "            responseResult = response.json()\n",
    "            print(\"API 响应内容：\")\n",
    "            print(responseResult)  # 打印完整的响应内容\n",
    "            \n",
    "            if 'error_code' in responseResult and responseResult['error_code'] == 0:\n",
    "                # API 可能直接返回数据，而不是嵌套在 'result' 中\n",
    "                data = responseResult\n",
    "                print(f\"\\n{consName}的{type}运势：\")\n",
    "                print(f\"综合指数：{data.get('all', '未知')}\")\n",
    "                print(f\"幸运色：{data.get('color', '未知')}\")\n",
    "                print(f\"幸运数字：{data.get('number', '未知')}\")\n",
    "                print(f\"健康指数：{data.get('health', '未知')}\")\n",
    "                print(f\"爱情指数：{data.get('love', '未知')}\")\n",
    "                print(f\"财运指数：{data.get('money', '未知')}\")\n",
    "                print(f\"工作指数：{data.get('work', '未知')}\")\n",
    "                print(f\"今日概述：{data.get('summary', '未知')}\")\n",
    "            else:\n",
    "                print(f\"请求失败：{responseResult.get('error_code', '未知错误')} - {responseResult.get('reason', '未知原因')}\")\n",
    "        else:\n",
    "            print(f\"网络请求失败，状态码：{response.status_code}\")\n",
    "    \n",
    "    except requests.RequestException as e:\n",
    "        print(f\"请求异常：{e}\")\n",
    "\n",
    "def main():\n",
    "    constellations = ['白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', \n",
    "                      '天秤座', '天蝎座', '射手座', '摩羯座', '水瓶座', '双鱼座']\n",
    "    \n",
    "    print(\"欢迎使用星座运势查询程序！\")\n",
    "    while True:\n",
    "        print(\"\\n请选择要查询的星座：\")\n",
    "        for i, cons in enumerate(constellations, 1):\n",
    "            print(f\"{i}. {cons}\")\n",
    "        print(\"0. 退出程序\")\n",
    "        \n",
    "        choice = input(\"请输入选项数字：\")\n",
    "        if choice == '0':\n",
    "            print(\"感谢使用，再见！\")\n",
    "            break\n",
    "        elif choice.isdigit() and 1 <= int(choice) <= 12:\n",
    "            consName = constellations[int(choice) - 1]\n",
    "            get_constellation_fortune(consName)\n",
    "        else:\n",
    "            print(\"无效的选择，请重试。\")\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "142b107a-2587-44aa-b594-4499f2982d00",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "===== 百度翻译程序 =====\n",
      "1. 翻译文本\n",
      "2. 查看翻译历史\n",
      "3. 退出\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请选择操作 (1/2/3):  1\n",
      "请输入要翻译的文本:  猪\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "翻译结果:\n",
      "1. 名. pig; swine ; [动] （哺乳动物） hog\n",
      "2. piglet ; porkling\n",
      "3. grunting of hogs\n",
      "4. sty; pigpen; hogpen; hog lot; hogcote\n",
      "5. pig's head; [电影]Dude, Where's My Car\n",
      "\n",
      "===== 百度翻译程序 =====\n",
      "1. 翻译文本\n",
      "2. 查看翻译历史\n",
      "3. 退出\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请选择操作 (1/2/3):  3\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "感谢使用，再见！\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "import json\n",
    "import os\n",
    "\n",
    "API_URL = \"https://fanyi.baidu.com/sug\"\n",
    "HISTORY_FILE = \"translation_history.txt\"\n",
    "\n",
    "def translate(text, from_lang='auto', to_lang='zh'):\n",
    "    data = {\n",
    "        'kw': text,\n",
    "        'from': from_lang,\n",
    "        'to': to_lang\n",
    "    }\n",
    "    try:\n",
    "        response = requests.post(API_URL, data=data)\n",
    "        response.raise_for_status()  # 检查请求是否成功\n",
    "        result = response.json()\n",
    "        \n",
    "        if 'data' in result and result['data']:\n",
    "            print(\"翻译结果:\")\n",
    "            for i, item in enumerate(result['data'], 1):\n",
    "                print(f\"{i}. {item['v']}\")\n",
    "            \n",
    "            # 保存翻译历史\n",
    "            save_history(text, result['data'][0]['v'])\n",
    "        else:\n",
    "            print(\"没有找到翻译结果。\")\n",
    "    except requests.RequestException as e:\n",
    "        print(f\"API请求失败: {e}\")\n",
    "    except json.JSONDecodeError:\n",
    "        print(\"返回的数据格式不正确。\")\n",
    "    except Exception as e:\n",
    "        print(f\"发生错误: {e}\")\n",
    "\n",
    "def save_history(original, translation):\n",
    "    with open(HISTORY_FILE, 'a', encoding='utf-8') as f:\n",
    "        f.write(f\"{original} -> {translation}\\n\")\n",
    "\n",
    "def view_history():\n",
    "    if os.path.exists(HISTORY_FILE):\n",
    "        with open(HISTORY_FILE, 'r', encoding='utf-8') as f:\n",
    "            print(\"翻译历史:\")\n",
    "            print(f.read())\n",
    "    else:\n",
    "        print(\"还没有翻译历史。\")\n",
    "\n",
    "def main_menu():\n",
    "    while True:\n",
    "        print(\"\\n===== 百度翻译程序 =====\")\n",
    "        print(\"1. 翻译文本\")\n",
    "        print(\"2. 查看翻译历史\")\n",
    "        print(\"3. 退出\")\n",
    "        choice = input(\"请选择操作 (1/2/3): \")\n",
    "\n",
    "        if choice == '1':\n",
    "            text = input(\"请输入要翻译的文本: \")\n",
    "            translate(text)\n",
    "        elif choice == '2':\n",
    "            view_history()\n",
    "        elif choice == '3':\n",
    "            print(\"感谢使用，再见！\")\n",
    "            break\n",
    "        else:\n",
    "            print(\"无效的选择，请重试。\")\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main_menu()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "58f85ea5-5209-4241-a521-71fcb7d86781",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "输入短信：【百度】您的验证码是：384952，有效期10分钟。请勿将验证码泄露给他人。\n",
      "识别结果：验证码短信\n",
      "提取信息：验证码 384952\n",
      "\n",
      "输入短信：【顺丰速递】您的快递已到达【银河系第三街道第四号柜】，取件码为：8861，请及时领取。如有问题请联系派送员13800138000。\n",
      "识别结果：快递通知短信\n",
      "提取信息：取件码 8861\n",
      "\n",
      "输入短信：这是一条普通的短信，不包含验证码或取件码。\n",
      "识别结果：未知类型短信\n",
      "提取信息：无法提取信息\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "def process_sms(sms):\n",
    "    # 验证码正则表达式\n",
    "    verification_pattern = r\"【(?P<sender>.*?)】.*验证码.*?(?P<code>\\d{4,6})\"\n",
    "    \n",
    "    # 快递取件码正则表达式\n",
    "    delivery_pattern = r\"【(?P<sender>.*?)】.*取件码.*?(?P<code>\\d{4,6})\"\n",
    "    \n",
    "    # 尝试匹配验证码\n",
    "    match = re.search(verification_pattern, sms)\n",
    "    if match:\n",
    "        return \"验证码短信\", f\"验证码 {match.group('code')}\"\n",
    "    \n",
    "    # 尝试匹配取件码\n",
    "    match = re.search(delivery_pattern, sms)\n",
    "    if match:\n",
    "        return \"快递通知短信\", f\"取件码 {match.group('code')}\"\n",
    "    \n",
    "    # 如果都不匹配\n",
    "    return \"未知类型短信\", \"无法提取信息\"\n",
    "\n",
    "# 测试函数\n",
    "def test_sms_processor():\n",
    "    test_cases = [\n",
    "        \"【百度】您的验证码是：384952，有效期10分钟。请勿将验证码泄露给他人。\",\n",
    "        \"【顺丰速递】您的快递已到达【银河系第三街道第四号柜】，取件码为：8861，请及时领取。如有问题请联系派送员13800138000。\",\n",
    "        \"这是一条普通的短信，不包含验证码或取件码。\"\n",
    "    ]\n",
    "    \n",
    "    for sms in test_cases:\n",
    "        print(f\"输入短信：{sms}\")\n",
    "        sms_type, info = process_sms(sms)\n",
    "        print(f\"识别结果：{sms_type}\")\n",
    "        print(f\"提取信息：{info}\")\n",
    "        print()\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    test_sms_processor()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ce69961c-7f25-4e2d-88f9-14404a6fd62d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "正在爬取第 1 页...\n",
      "等待 3.95 秒...\n",
      "正在爬取第 2 页...\n",
      "等待 3.72 秒...\n",
      "正在爬取第 3 页...\n",
      "等待 4.79 秒...\n",
      "正在爬取第 4 页...\n",
      "等待 4.11 秒...\n",
      "正在爬取第 5 页...\n",
      "等待 2.82 秒...\n",
      "正在爬取第 6 页...\n",
      "等待 2.34 秒...\n",
      "正在爬取第 7 页...\n",
      "爬取页面 https://movie.douban.com/subject/1292052/comments?start=120&limit=20&status=P&sort=new_score 时发生错误: 403 Client Error: Forbidden for url: https://movie.douban.com/subject/1292052/comments?start=120&limit=20&status=P&sort=new_score\n",
      "等待 4.46 秒...\n",
      "正在爬取第 8 页...\n",
      "爬取页面 https://movie.douban.com/subject/1292052/comments?start=140&limit=20&status=P&sort=new_score 时发生错误: 403 Client Error: Forbidden for url: https://movie.douban.com/subject/1292052/comments?start=140&limit=20&status=P&sort=new_score\n",
      "等待 3.71 秒...\n",
      "正在爬取第 9 页...\n",
      "爬取页面 https://movie.douban.com/subject/1292052/comments?start=160&limit=20&status=P&sort=new_score 时发生错误: 403 Client Error: Forbidden for url: https://movie.douban.com/subject/1292052/comments?start=160&limit=20&status=P&sort=new_score\n",
      "等待 3.22 秒...\n",
      "正在爬取第 10 页...\n",
      "爬取页面 https://movie.douban.com/subject/1292052/comments?start=180&limit=20&status=P&sort=new_score 时发生错误: 403 Client Error: Forbidden for url: https://movie.douban.com/subject/1292052/comments?start=180&limit=20&status=P&sort=new_score\n",
      "等待 2.37 秒...\n",
      "评论已保存到 shawshank_redemption_comments_part1.csv\n",
      "评论已保存到 shawshank_redemption_comments_all.csv\n",
      "爬取完成，耗时 40.32 秒\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "from bs4 import BeautifulSoup\n",
    "import csv\n",
    "import time\n",
    "import random\n",
    "\n",
    "def scrape_comments(url):\n",
    "    headers = {\n",
    "        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'\n",
    "    }\n",
    "    try:\n",
    "        response = requests.get(url, headers=headers)\n",
    "        response.raise_for_status()  # 如果请求不成功则抛出异常\n",
    "        soup = BeautifulSoup(response.text, 'html.parser')\n",
    "        \n",
    "        comments = []\n",
    "        for comment in soup.find_all('div', class_='comment-item'):\n",
    "            try:\n",
    "                comment_info = comment.find('span', class_='comment-info')\n",
    "                if comment_info and comment_info.a:\n",
    "                    username = comment_info.a.text.strip()\n",
    "                else:\n",
    "                    username = \"Unknown\"\n",
    "                \n",
    "                rating = comment.find('span', class_='rating')\n",
    "                rating = rating['title'].split()[0] if rating else 'No Rating'\n",
    "                \n",
    "                comment_time = comment.find('span', class_='comment-time')\n",
    "                time_str = comment_time.text.strip() if comment_time else \"Unknown Time\"\n",
    "                \n",
    "                content_span = comment.find('span', class_='short')\n",
    "                content = content_span.text.strip() if content_span else \"No Content\"\n",
    "                \n",
    "                comments.append([username, rating, time_str, content])\n",
    "            except Exception as e:\n",
    "                print(f\"解析评论时发生错误: {e}\")\n",
    "                continue\n",
    "        \n",
    "        return comments\n",
    "    except requests.RequestException as e:\n",
    "        print(f\"爬取页面 {url} 时发生错误: {e}\")\n",
    "        return []\n",
    "\n",
    "def main():\n",
    "    base_url = \"https://movie.douban.com/subject/1292052/comments\"\n",
    "    urls = [f\"{base_url}?start={20*i}&limit=20&status=P&sort=new_score\" for i in range(10)]\n",
    "    \n",
    "    all_comments = []\n",
    "    for i, url in enumerate(urls):\n",
    "        print(f\"正在爬取第 {i+1} 页...\")\n",
    "        comments = scrape_comments(url)\n",
    "        all_comments.extend(comments)\n",
    "        \n",
    "        # 添加随机延迟，在2到5秒之间\n",
    "        delay = random.uniform(2, 5)\n",
    "        print(f\"等待 {delay:.2f} 秒...\")\n",
    "        time.sleep(delay)\n",
    "        \n",
    "        # 每爬取10页，保存一次结果\n",
    "        if (i + 1) % 10 == 0:\n",
    "            save_to_csv(all_comments, f'shawshank_redemption_comments_part{(i+1)//10}.csv')\n",
    "    \n",
    "    # 最后保存所有结果\n",
    "    save_to_csv(all_comments, 'shawshank_redemption_comments_all.csv')\n",
    "\n",
    "def save_to_csv(comments, filename):\n",
    "    with open(filename, 'w', newline='', encoding='utf-8-sig') as file:\n",
    "        writer = csv.writer(file)\n",
    "        writer.writerow(['用户名', '评分', '评论时间', '评论内容'])\n",
    "        writer.writerows(comments)\n",
    "    print(f\"评论已保存到 {filename}\")\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    start_time = time.time()\n",
    "    main()\n",
    "    end_time = time.time()\n",
    "    print(f\"爬取完成，耗时 {end_time - start_time:.2f} 秒\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5df1c26a-1369-4b0f-81aa-07f74983efaf",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a528d161-9f4d-43d3-b21d-b3f15799f34d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
